/*
 * intrusive_ptr.h
 *
 *  Created on: 2008-12-27
 *      Author: ant
 */

#ifndef INTRUSIVE_PTR_H_
#define INTRUSIVE_PTR_H_

#include "bits/config.h"

BEGIN_NAMESPACE_TOXIC

template<class T>
class intrusive_ptr {
public:
    intrusive_ptr()
    :p_(0) {
    }

    intrusive_ptr(T* p, bool add_ref = true)
    :p_(p) {
        if (p_ != 0 && add_ref) {
        	intrusive_ptr_add_ref(p_);
        }
    }

    intrusive_ptr(const intrusive_ptr& rhs)
    :p_(rhs.p_) {
        if (p_ != 0) {
        	intrusive_ptr_add_ref(p_);
        }
    }

    ~intrusive_ptr() {
        if (p_ != 0) {
        	intrusive_ptr_release(p_);
        }
    }

    intrusive_ptr& operator=(const intrusive_ptr& rhs) {
    	intrusive_ptr(rhs).swap(*this);
        return *this;
    }

    T* get() const {
        return p_;
    }

    T& operator*() const {
        return *p_;
    }

    T* operator->() const {
        return p_;
    }

    void swap(intrusive_ptr& rhs) {
        T* tmp = p_;
        p_ = rhs.p_;
        rhs.p_ = tmp;
    }

private:
    T* p_;
};

END_NAMESPACE_TOXIC

#endif /* INTRUSIVE_PTR_H_ */
